feat: add Pump and LiquidStream to process domain#1516
Draft
Conversation
- LiquidProcessUnit ABC: typed boundary for incompressible liquid units - LiquidStream value object: pressure, density, mass rate; volumetric_rate, standard_density_gas_phase_after_flash, standard_rate_sm3_per_day, with_mass_rate() - Pump: LiquidProcessUnit backed by UserDefinedChartData, computes head/efficiency from chart interpolation, raises RateTooLowError / RateTooHighError, exposes get_shaft_power_mw()
…w control - RecirculationLoop now accepts Pump (LiquidProcessUnit) as inner process, in addition to Compressor and ProcessSystem - DirectMixer/DirectSplitter work with both FluidStream and LiquidStream via duck-typed standard_density_gas_phase_after_flash / with_mass_rate() - LiquidStream.standard_density_gas_phase_after_flash returns density_kg_per_m3 (standard ≈ actual for incompressible liquids, consistent with legacy PumpModel) - RecirculationLoop.get_shaft_power_mw() delegates to inner Pump - All test files updated to use RecirculationLoop/DirectMixer/DirectSplitter directly with Sm3/day rates
…bounds to Pump - ShaftConnectable Protocol: minimum_speed, maximum_speed, set_speed() - Shaft is now generic Shaft[T: ShaftConnectable] — a shaft drives either compressors or pumps, never a mix of both; enforced at the type level - Shaft._compressors renamed to _units; connect()/get_speed_boundary() use the protocol instead of importing Compressor directly - Compressor gains minimum_speed / maximum_speed properties (delegates to compressor_chart) to satisfy ShaftConnectable - Pump gains minimum_speed / maximum_speed properties (delegates to pump_chart) to satisfy ShaftConnectable — a pump shaft is now a VariableSpeedShaft[Pump]
…otocol - Add RecirculatingUnit protocol (get_id, maximum_flow_rate, get_recirculation_range) - Pump implements RecirculatingUnit via minimum_flow_rate, maximum_flow_rate, get_recirculation_range() - Replace Compressor with RecirculatingUnit in all strategy classes: - anti_surge/common_asv.py: first_compressor → first_unit - anti_surge/individual_asv.py: compressors → units - pressure_control/common_asv.py: first_compressor → first_unit - pressure_control/individual_asv.py: compressors → units - Replace FluidStream with Any in all solver/strategy method signatures: - outlet_pressure_solver.py, anti_surge_strategy.py, pressure_control_strategy.py - common_asv.py (both anti_surge and pressure_control), individual_asv.py (both) - ProcessRunner.run() and ProcessSystemRunner._propagate_stream_to_id() accept Any stream - Update all call sites in mapper and tests (first_compressor= → first_unit=, compressors= → units=) - Fix pump._head_and_efficiency → _head_and_efficiency_at_rate rename
…t to GasProcessUnit - ProcessUnit is now the stream-agnostic protocol (get_id + propagate_stream) - GasProcessUnit is the gas-specific ABC extending Entity - Detach DirectMixer/DirectSplitter from ABC hierarchy (standalone, uuid7) - Move protocol from stream_protocol.py to process_pipeline/process_unit.py - Add pump integration tests (speed solver, shaft power, recirculation) - Clean up FluidStream.standard_density docstring
- Rename first_compressor → first_unit in new ASV test factories - Fix FluidStream → StreamWithPressure type annotation in individual_asv.py - xfail pump recirculation test pending boundary calculation investigation
The regression test from PR #1515 used first_compressor= kwarg which was renamed to first_unit= on this branch. Also remove xfail from pump recirculation test since the underlying bug is now fixed on main.
Widen choke solver and pressure control strategy signatures from FluidStream to StreamWithPressure for consistency. Add pyright ignore comments where cached_property on FluidStream prevents structural protocol matching (a known basedpyright limitation with cached_property vs @Property in protocols). Add propagate_stream to RecirculatingUnit protocol.
Replace Generic[_T] with PEP 695 class Shaft[T: ShaftConnectable] syntax, as required by ruff UP046.
071ad44 to
35faa36
Compare
Convert remaining Generic[T]/TypeVar usages to PEP 695 syntax: - Shaft, SingleSpeedShaft, VariableSpeedShaft - Overflow, CommonStreamDistribution - Builder (yaml_builder) Remove unused TYamlClass TypeVar and YamlBase import. Fix import sorting (ruff I001) and UP035 (typing_extensions).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds pump and liquid stream support to the process domain, enabling pump trains to use the same solver infrastructure as compressor trains — speed solving, anti-surge recirculation, and pressure control.
This is Phase 1: the domain layer entities, protocols, and solver integration. YAML wiring (schema, mapper, result assembly) is Phase 2 and will follow in a separate PR.
What's included
New entities
Pump— process unit implementingProcessUnitprotocol. Variable-speed, chart-based head/efficiency lookup,propagate_stream(LiquidStream) → LiquidStreamLiquidStream— frozen dataclass for incompressible fluids (pressure, density, mass rate). ImplementsMixableStreamandStreamWithPressureprotocolsLiquidProcessUnit— ABC for process units operating on liquid streamsProtocol generalisation
ProcessUnitprotocol made stream-agnostic viaStreamWithPressure(was hardcoded toFluidStream)RecirculatingUnitprotocol extracted for units that expose capacity boundaries (compressor + pump)ShaftConnectableprotocol soShaftworks with bothCompressorandPumpMixableStreamprotocol soDirectMixer/DirectSplitterwork with both gas and liquid streamsProcessUnitABC →GasProcessUnitto avoid collision with the protocolSolver support
OutletPressureSolver, anti-surge strategies, and pressure control strategies all work with pumps — no pump-specific solver code neededRecirculationLoop,DirectMixer,DirectSplittersupport liquid streams via protocol dispatchTests
PumpSingleSpeedcalculations)What's NOT included (Phase 2)
Type of Work